class IndexTable {
    constructor(db, tableName) {
        this.db = db;
        this.tableName = tableName;
    }

    add(data, key) {
        const self = this;
        return new Promise((resolve, reject) => {
            const request = self.db.transaction([self.tableName], 'readwrite')
                .objectStore(self.tableName)
                .add(data, key);

            request.onsuccess = function (event) {
                console.log('数据写入成功');
                resolve(event);
            };

            request.onerror = function (event) {
                console.log('数据写入失败');
                reject(event.target.error);
            };
        });
    }

    set(data, key) {
        const self = this;
        return new Promise((resolve, reject) => {
            const request = self.db.transaction([self.tableName], 'readwrite')
                .objectStore(self.tableName)
                .put(data, key);

            request.onsuccess = function (event) {
                console.log('数据更新成功');
                resolve(event);
            };

            request.onerror = function (event) {
                console.log('数据更新失败');
                reject(event.target.error);
            };
        });
    }

    delete(key) {
        const self = this;
        return new Promise((resolve, reject) => {
            var request = self.db.transaction([self.tableName], "readwrite")
                .objectStore(self.tableName)
                .delete(key);
            request.onsuccess = function (event) {
                // 删除成功！
                console.log('数据删除成功！');
                resolve(event);
            };
            request.onerror = function (event) {
                console.log('数据删除失败');
                reject(event.target.error);
            }
        });
    }

    get(key) {
        const self = this;
        return new Promise((resolve, reject) => {
            var transaction = self.db.transaction([self.tableName]);
            var objectStore = transaction.objectStore(self.tableName);
            console.log('objectStore', objectStore);
            var request = objectStore.get(key);

            request.onerror = function (event) {
                console.log('事务失败');
                reject(event.target.error);
            };

            request.onsuccess = function (event) {
                resolve(request.result);
            };
        });
    }

    getByIndex(indexName, value) {
        const self = this;
        return new Promise((resolve, reject) => {
            var transaction = self.db.transaction([self.tableName], 'readonly');
            var store = transaction.objectStore(self.tableName);
            var index = store.index(indexName);
            var request = index.get(value);

            request.onsuccess = function (e) {
                var result = e.target.result;
                resolve(result);
            };
        });
    }

    checkMatchKey(keyReg, keyName) {
        if (keyReg) {
            return keyReg.test(keyName);
        }
        return true;
    }

    checkMatch(match, value) {
        for (let k in match) {
            if (k === 'key') {
                continue
            }
            console.log(k, match[k], value[k]);
            if (match[k].test(value[k])) {
                continue
            }
            return false
        }
        return true
    }

    getAll(match, start, count) {
        const self = this;
        const records = [];
        return new Promise((resolve, reject) => {
            const objectStore = self.db.transaction(self.tableName, IDBTransaction.READ_ONLY).objectStore(self.tableName);
            objectStore.openCursor().onsuccess = (event) => {
                var cursor = event.target.result;
                if (cursor) {
                    if (!match || (this.checkMatchKey(match.key, cursor.key) && this.checkMatch(match, cursor.value))) {
                        records.push({ key: cursor.key, value: cursor.value });
                        if (count && records.length >= count) {
                            console.log('已经获取足够数据了！');
                            resolve(records);
                            return
                        }
                    }
                    cursor.continue();
                } else {
                    console.log('没有更多数据了！');
                    resolve(records);
                }
            };
        });
    }
}
class IndexDB {
    database = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
    //tables = new Map();
    constructor(DB_NAME, DB_VERSION) {
        if (!this.database) {
            //throw new Error('您的浏览器不支持indexedDB，建议使用最新版本的chrome浏览器');
            return false;
        }
        this.DB_NAME = DB_NAME;
        this.DB_VERSION = DB_VERSION;
    }

    init(tables) {
        //const self = this;
        const conn = this.database.open(this.DB_NAME, this.DB_VERSION);
        const stores = tables || [];
        return new Promise((resolve, reject) => {
            conn.onsuccess = (e) => {
                console.log('connect database success', e.target.result);
                const innerStore = e.target.result;
                this.db = innerStore;
                resolve(true);
            };
            conn.onerror = (e) => {
                console.log('open database failed', e.target.errorCode);
                reject(e);
            };
            conn.onupgradeneeded = (e) => {
                const innerStore = e.target.result;
                this.db = innerStore;
                stores.forEach((store) => {
                    console.log('store', store);
                    if (true || !innerStore.objectStoreNames.contains(store.name)) {
                        const storeObj = innerStore.createObjectStore(store.name, store.params || {});
                        if (store.indexes && store.indexes.length) {
                            store.indexes.forEach((indexInfo) => {
                                console.log('create index', indexInfo);
                                storeObj.createIndex(indexInfo.name, indexInfo.key, {
                                    unique: indexInfo.unique || false
                                });
                            });
                        }
                    }
                });
                console.log('upgrade database success');
            }
        })
    }

    choose(tableName) {
        return new IndexTable(this.db, tableName);
    }

    removeDB(DB_NAME) {
        try {
            this.database.deleteDatabase(DB_NAME);
        } catch (event) {
            console.log(event.getMessage);
            reject(event.target.error)
        }
    }
}